package com.zxpic.web;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.sleepycat.je.DatabaseException;

public class ImageServlet extends HttpServlet {
	private static final long serialVersionUID = 9026192552752931773L;
	private static final String DEFAULT_ENCODING = "utf-8";

	public static final BerkeleyDBUtils imgBdb = new BerkeleyDBUtils("./bdb/images");

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String path = req.getPathInfo();
		if (path.indexOf("/show/") > -1) {
			Pattern pt = Pattern.compile("[\\d]+", Pattern.DOTALL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
			Matcher m = pt.matcher(path);
			String id = null;
			if (m.find())
				id = m.group();
			try {
				byte[] b = imgBdb.getByte(String.valueOf(id).getBytes(DEFAULT_ENCODING));
				resp.getOutputStream().write(b);
				resp.getOutputStream().flush();
			} catch (DatabaseException e) {
				e.printStackTrace();
			}

		}
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String path = req.getPathInfo();
		if (path.indexOf("/upload") > -1) {
			try {
				Map<String, Object> map = uploadFile(req);

				if (map != null && map.containsKey("byteContent")) {
					String imgId = getImgId();
					imgBdb.putByte(imgId.getBytes(DEFAULT_ENCODING), (byte[]) map.get("byteContent"));
					imgBdb.getMyDbEnvironment().sync();

					String reStr = "<script>";
					reStr += "window.parent.uploadAfter('" + imgId + "');";
					reStr += "</script>";
					resp.getWriter().println(reStr);
					resp.getWriter().flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else if (path.indexOf("/crop") > -1) {

		} else if (path.indexOf("/rotate") > -1) {
			String imgId = req.getParameter("imgId");
			String degree = req.getParameter("degree");
			try {
				byte[] key = imgId.getBytes(DEFAULT_ENCODING);
				byte[] byte1 = imgBdb.getByte(key);
				BufferedImage srcImg = ImageIO.read(new ByteArrayInputStream(byte1));
				srcImg = ImageUtils.rotate(srcImg, Integer.valueOf(degree));
				ByteArrayOutputStream output = new ByteArrayOutputStream();
				ImageIO.write(srcImg, "jpeg", output);

				String newImgId = getImgId();
				imgBdb.deleteByte(key);
				byte[] byteArray = output.toByteArray();
				System.out.println(byteArray.length);
				imgBdb.putByte(newImgId.getBytes(DEFAULT_ENCODING), byteArray);
				imgBdb.getMyDbEnvironment().sync();

				String reStr = "{\"imgId\":" + newImgId + "}";
				resp.getWriter().println(reStr);
				resp.getWriter().flush();
			} catch (DatabaseException e) {
				e.printStackTrace();
			}

		}
	}

	private String getImgId() {
		int id = new java.util.Random().nextInt(1000000);
		String imgId = String.valueOf(id);
		return imgId;
	}

	private static Map<String, Object> uploadFile(HttpServletRequest request) throws Exception, UnsupportedEncodingException {
		Map<String, Object> values = new HashMap<String, Object>();

		FileItemFactory factory = new DiskFileItemFactory();
		// 通过该工厂对象创建ServletFileUpload对象
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding(DEFAULT_ENCODING);
		upload.setSizeMax(1024 * 1024 * 4);
		// 将转化请求保存到list对象中
		List<?> items;
		try {
			items = upload.parseRequest(request);
		} catch (FileUploadException e) {
			e.printStackTrace();
			// 上传文件不能大于1M
			throw new RuntimeException("上传文件不能大于4M");
		}
		// 循环list中的对象
		if (items != null) {
			for (Object obj : items) {
				FileItem fileItem = (FileItem) obj;
				if (!fileItem.isFormField()) {// 如果该FileItem不是表单域
					long size = fileItem.getSize();
					if (size > 2 * 1024 * 1024) {
						// 上传文件不能大于1M
						throw new RuntimeException("上传文件不能大于2M");
					}
					values.put("filename", fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") + 1));
					values.put("byteContent", processUploadedFile(fileItem.getInputStream()));
					fileItem.delete();// 内存中删除该数据流
				} else {
					String value = fileItem.getString(DEFAULT_ENCODING);
					values.put(fileItem.getFieldName(), value);
				}
			}
		}
		return values;
	}

	private static byte[] processUploadedFile(InputStream in) throws Exception {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024 * 8]; // To hold file contents
		int bytes_read;
		while ((bytes_read = in.read(buffer)) != -1) // Read until EOF
		{
			out.write(buffer, 0, bytes_read);
		}
		byte[] byteArray = out.toByteArray();
		if (in != null)
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		if (out != null)
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		return byteArray;
	}
}
